#pragma once
#include <thread_pool.h>

#include <memory>
#include <mutex>
#include <queue>
#include <semaphore.h>
#include <thread>
#include <vector>
#include <atomic>

class ThreadPoolImpl : public ThreadPool {
public:
    static sptr<ThreadPoolImpl> GetInstance();

    virtual void PostTask(ThreadPoolTask task, std::string name) override;

private:
    ThreadPoolImpl();
    ~ThreadPoolImpl();
    static inline sptr<ThreadPoolImpl> instance = nullptr;

    void WorkThreadMain(int id);

    struct Task {
        ThreadPoolTask task;
        std::string name;
    };

    std::queue<Task> tasks;
    std::mutex tasksMutex;
    std::vector<std::unique_ptr<std::thread>> workThreads;
    sem_t taskSem;
    std::atomic<bool> running = true;
};
